package fr.umlv.escapeir.ship;

import java.awt.Image;

import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.Vec2;

import fr.umlv.escapeir.GameWorld;
import fr.umlv.escapeir.game.LinearMove;
import fr.umlv.escapeir.game.WorldActor;
import fr.umlv.escapeir.gesture.Direction;

abstract class ShipFactoryDescription {
	protected Image image;
	protected PolygonShape shape;
	protected Vec2 topLeft;
	protected Vec2 bottomRight;
	
	Image image() {return image;}
	PolygonShape shape() {return shape;}
	Vec2 topLeft() {return topLeft;}
	Vec2 bottomRight() {return bottomRight;}
}

public class ShipFactory {
	private final GameWorld world;
	
	public ShipFactory (GameWorld gameWorld) {
		world = gameWorld;
	}
	
	public HeroShip createHeroShip () {
		ShipFactoryDescription desc = ShipType.HERO.desc();
		HeroShip ship = HeroShip.createInWorld(world,
				desc.shape(), desc.image(),
				desc.topLeft(), desc.bottomRight());
		return ship;
	}
	
	public EnnemyShip createEnnemy(String shipName, float x, float y) throws ShipCreationException {
		ShipType type = ShipType.valueOf(shipName);
		if (type.type() != WorldActor.Type.ENNEMY) throw new ShipCreationException();
		ShipFactoryDescription desc = type.desc();
		EnnemyShip ship = EnnemyShip.createInWorld(world, x, y,
				desc.shape(), desc.image(),
				desc.topLeft(), desc.bottomRight());
		ship.setBehavior(new LinearMove(ship.getBody(), Direction.DOWN, 100, -1));
		return ship;
	}
	
	public String[] getShipTypes () {
		ShipType types[] = ShipType.values();
		String names[] = new String[types.length];
		for(int i = 0; i<types.length;++i)
			names[i] = types[i].toString();
		return names;
	}
	
	enum ShipType {
		JUPITER(new JupiterShipDescription(), WorldActor.Type.ENNEMY),
		MOON(new MoonShipDescription(), WorldActor.Type.ENNEMY),
		EARTH(new EarthShipDescription(), WorldActor.Type.ENNEMY),
		HERO(new HeroShipDescription(), WorldActor.Type.HERO);
		
		private final ShipFactoryDescription desc;
		private final WorldActor.Type type;
		
		ShipType(ShipFactoryDescription desc, WorldActor.Type type) {
			this.desc = desc;
			this.type = type;
		}
		ShipFactoryDescription desc() {return desc;}
		WorldActor.Type type() {return type;}
	}
}
